package com.shark.manager.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.shark.commons.base.exception.AppException;
import com.shark.commons.base.service.BaseService;
import com.shark.commons.utils.BeanUtils;
import com.shark.manager.system.dao.MenuMapper;
import com.shark.manager.system.entity.Menu;
import com.shark.manager.system.exception.MenuCodeExistException;
import com.shark.manager.system.exception.MenuNameExistException;
import com.shark.manager.system.exception.UserEmailExistException;
import com.shark.manager.system.service.MenuService;

@Service
public class MenuServiceImpl extends BaseService<Menu> implements MenuService {

	@Autowired
	private MenuMapper mapper ;
	
	@Override
	@CacheEvict(value="MenuCache", allEntries=true)
	public int insertSelective(Menu entity) throws AppException {
		if(super.existsFileldValue(null, "fullname", entity.getFullname()) > 0) 
			throw new MenuNameExistException("该菜单名称已被使用");
		if(super.existsFileldValue(null, "code", entity.getCode()) > 0) 
			throw new MenuCodeExistException("该菜单编码已存在");
		
		this.mapper.defaultSelect();
		
		entity.setSortcode(this.mapper.nextSort(entity.getPid(), entity.getId())) ;
		
		return super.insertSelective(entity);
	}
	
	@Override
	@CacheEvict(value="MenuCache", allEntries=true)
	public int updateByPrimaryKeySelective(Menu entity) throws AppException {
		if(super.existsFileldValue(entity.getId(), "fullname", entity.getFullname()) > 0) 
			throw new MenuNameExistException("该菜单名称已存在");
		if(super.existsFileldValue(entity.getId(), "code", entity.getCode()) > 0) 
			throw new UserEmailExistException("该菜单编码已存在");
		
		Menu menu = selectByPrimaryKey(entity.getId()) ;
		if (null != entity.getPid() && !"".equals(entity.getPid())) {
			if(menu.getId().equals(entity.getPid())) {
				throw new AppException("操作有误，父模块服务关联自己！");
			}
		}
		this.mapper.defaultSelect();
		entity.setModifyTime(new Date());
		
		return super.updateByPrimaryKeySelective(entity);
	}
	
	
	@Override
	@CacheEvict(value="MenuCache", allEntries=true)
	public int deleteByPrimaryKey(Object id) throws AppException {
		del(selectByPrimaryKey(id));
		return super.deleteByPrimaryKey(id);
	}
	private void del(Menu record) {
		List<Menu> rs = this.mapper.findMenuByCatalogId(record.getId().intValue()) ;
		if(null != rs && !rs.isEmpty()) {
			for (Menu resource : rs) {
				del(resource);
			}
		}
		super.deleteByPrimaryKey(record.getId()) ;
	}
	
	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#key+\")\")")
	@Override
	public Menu selectByPrimaryKey(Object id) {
		return super.selectByPrimaryKey(id);
	}
	
	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#location+\")\")")
	@Override
	public Menu getLocation(String location) {
		Menu menu = this.mapper.getLocation(location) ;
		menu.setText(menu.getFullname());
		return menu;
	}

	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName")
	@Override
	public List<Menu> findMenuChildByCatalog() {
		List<Menu> menus = new ArrayList<Menu>() ;
		List<Menu> catalogList = this.findAllMenuByTopCatalog() ;
		for (Menu menu : catalogList) {
			menus.add(this.recursiveMenuCatalog(menu)) ;
		}
		return menus;
	}

	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName + (\"(\"+#catalog_id+\")\")")
	@Override
	public List<Menu> findMenuChildrenViewByPid(Integer catalog_id) {
		List<Menu> menus = new ArrayList<Menu>() ;
		
		List<Menu> childrens = this.mapper.findMenuByCatalogId(catalog_id) ;
		for (Menu menu : childrens) {
			menus.add(this.recursiveMenu(menu)) ;
		}
		return menus ;
	}

	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName")
	@Override
	public List<Menu> findAllMenuViewByTopCatalog() {
		List<Menu> catelogs = new ArrayList<Menu>() ;
		List<Menu> findAllMenuByTopCatalog = this.mapper.findAllMenuByTopCatalog() ;
		for (Menu menu : findAllMenuByTopCatalog) {
			Menu m = new Menu() ;
			BeanUtils.copyNotNullProperties(menu, m);
			m.setHref(menu.getLocation());
			m.setText(menu.getFullname());
			catelogs.add(m) ;
		}
		
		return catelogs ;
	}

	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName")
	@Override
	public List<Menu> treegrid() {
		List<Menu> menus = new ArrayList<Menu>() ;
		List<Menu> catalogList = this.findAllMenuByTopCatalog() ;
		for (Menu menu : catalogList) {
			menus.add(this.recursiveMenu(menu)) ;
		}
		return menus;
	}

	@Cacheable(value="MenuCache" ,key="#root.targetClass +\".\"+ #root.methodName")
	@Override
	public List<Menu> findAllMenuByTopCatalog() {
		return this.mapper.findAllMenuByTopCatalog();
	}
	
	
	/**
	 * 递归筛选目录
	 * @param entity
	 * @return
	 */
	private Menu recursiveMenuCatalog(Menu entity) {
		entity.setText(entity.getFullname());
		entity.setIconCls("icon-standard-application-view-list");
		
		List<Menu> childs = this.mapper.findMenuChildByCatalog(entity.getId().intValue());
		
		if(null != childs && !childs.isEmpty()) {
			List<Menu> children = new ArrayList<Menu>() ;
			
			for (Menu r : childs) {
				if(null != r) {
					children.add(recursiveMenuCatalog(r)); 
				}
			}
			entity.setChildren(children);
		}
		return entity ;
	}
	
	/**
	 * 递归
	 * @param entity
	 * @return
	 */
	private Menu recursiveMenu(Menu entity) {
		entity.setHref(entity.getLocation());
		entity.setText(entity.getFullname());
		entity.setIconCls("icon-standard-application-view-list");
		List<Menu> childs = this.mapper.findMenuByCatalogId(entity.getId().intValue());
		if(null != childs && !childs.isEmpty()) {
			List<Menu> children = new ArrayList<Menu>() ;
			
			for (Menu r : childs) {
				if(null != r) {
					children.add(recursiveMenu(r)); 
				}
			}
			entity.setChildren(children);
		}
		return entity ;
	}
	
}
